package com.yanqu.road.server.manger.config;

import com.yanqu.road.logic.bussiness.config.HuntBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.config.hunt.HuntBoxReward;
import com.yanqu.road.entity.config.hunt.HuntMonster;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.system.NormalWeightItem;
import com.yanqu.road.entity.enums.ePatronsSkillType;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.hunt.HuntBox;
import com.yanqu.road.entity.hunt.HuntTimeData;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.player.UserPatronsSkill;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.servercenter.TitleInfo;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class HuntConfigMgr extends TempMgr {

    private static Logger logger = LogManager.getLogger(HuntConfigMgr.class.getName());

    private static List<HuntMonster> huntMonsterList;

    private static RandomHelper threadSafeRandom = new RandomHelper();

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean reloadConfig() {
        huntMonsterList = HuntBussiness.getHuntMonsterList();
        if(huntMonsterList.size() <= 0){
            return false;
        }
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static boolean isHuntSystemOpenTime(){
        ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
        int days = DateHelper.calc2DateTDOADays(new Date(serverInfo.getOpenTime() * 1000), new Date());
        return days >= GameConfig.SEVER_OPEN_AFTER_DAYS_OPEN_HUNT;
    }

    public static boolean isInHuntBattleTime(){
        HuntTimeData huntTimeData = ConfigMgr.getHuntTimeData();
        if(null == huntTimeData){
            return false;
        }
        Calendar calNow = Calendar.getInstance();
        int hour =  calNow.get(Calendar.HOUR_OF_DAY);
        int minute = calNow.get(Calendar.MINUTE);
        if(hour > huntTimeData.getStartHour()){
            if(hour < huntTimeData.getEndHour()){
                return true;
            }else if(hour == huntTimeData.getEndHour()){
                return minute < huntTimeData.getEndMinute();
            }
        }else if(hour == huntTimeData.getStartHour()){
            if(minute >= huntTimeData.getStarMinute()){
                if(hour < huntTimeData.getEndHour()){
                    return true;
                }else if(hour == huntTimeData.getEndHour()){
                    return minute < huntTimeData.getEndMinute();
                }
            }
        }
        return false;
    }

    public static boolean isTodayHuntFinish(int monsterIndex){
        return monsterIndex > huntMonsterList.size() - 1;
    }

    public static HuntMonster getHuntMonster(int monsterIndex){
        return huntMonsterList.get(monsterIndex);
    }

    public static int getRandomHuntBoxId(HuntMonster huntMonster){
        int totalWeight = 0;
        for(NormalWeightItem weightItem : huntMonster.getWeightItemList()){
            totalWeight += weightItem.getWeight();
        }
        int randomWeight = threadSafeRandom.next(0, totalWeight);
        int tempWeight = 0;
        for (NormalWeightItem weightItem : huntMonster.getWeightItemList()) {
            tempWeight += weightItem.getWeight();
            if (tempWeight >= randomWeight) {
                return weightItem.getValue().intValue();
            }
        }
        return 0;
    }

    public static int getPatronsMaxHuntBattleTimes(GamePlayer player, int patronsId){
        int times = GameConfig.HUNT_PATRONS_DEFAULT_BATTLE_TIMES;
        UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(patronsId);
        if(null != userPatrons){
            for(UserPatronsSkill patronsSkill : userPatrons.getSkillList()){
                if(patronsSkill.getType() != ePatronsSkillType.Talent.getValue()){
                    continue;
                }
                SkillInfo skillInfo = SkillMgr.getSkillInfo(patronsSkill.getSkillId());
                if(skillInfo.getType() == eSkillType.HuntAddPatronsBattleTimes.getValue()){
                    times += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getSkillLv());
                }
            }
        }
        return times;
    }

    public static Property getHuntMonsterReward(GamePlayer player, HuntMonster huntMonster){
        Property reward = new Property();
        reward.addProperty(huntMonster.getReward());
        int silverRandom = threadSafeRandom.next(huntMonster.getSilverMinParam(), huntMonster.getSilverMaxParam() + 1);
        BigInteger silverCount = player.getUserInfo().getEarnSpeed().multiply(BigInteger.valueOf(silverRandom));
        reward.addProperty(GameConfig.GAME_MONEY_SILVER, silverCount);
        int patronsExpRandom = threadSafeRandom.next(huntMonster.getPatronsExpMinParam(), huntMonster.getPatronsExpMaxParam() + 1);
        TitleInfo titleInfo = TitleMgr.getTitleInfo(player.getTitleId());
        reward.addProperty(GameConfig.GAME_MONEY_PATRONS_EXP, BigInteger.valueOf(titleInfo.getChildTrainAddExp()).multiply(BigInteger.valueOf(patronsExpRandom)));
        return reward;
    }

    public static HuntBoxReward getHuntBoxReward(HuntBox huntBox){
        if(huntBox.getHuntBoxRewardList().size() > 0) {
            int randomdValue = threadSafeRandom.next(0, huntBox.getHuntBoxRewardList().size());
            HuntBoxReward huntBoxReward = huntBox.getHuntBoxRewardList().get(randomdValue);
            huntBox.getHuntBoxRewardList().remove(randomdValue);
            return huntBoxReward;
        }
        return null;
    }

    public static int getHuntWavesCount(){
        return huntMonsterList.size();
    }
}
